package com.ruben.study;

import java.util.Collections;
import java.util.List;
import java.util.Spliterator;
import java.util.Spliterators;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;

/**
 * Stream源码研究
 *
 * @author <achao1441470436@gmail.com>
 * @since 2021/7/25 0025 16:21
 */
public class StreamSourceDemo {
    public static void main(String[] args) {
        spliterator();
    }

    private static void spliterator() {
        // 生成0-99的元素
        List<Integer> list = Stream.iterate(0, i -> i < 100, i -> ++i).toList();
        // 获取集合的Spliterator
        Spliterator<Integer> spliterator = list.spliterator();
        // 通过Spliterators获取
        Spliterator<String> spliterator1 = Spliterators.spliterator(Collections.singleton("xxx"), 0);
        // 按顺序消费元素，返回值表示是否还有下一个
        boolean b = spliterator.tryAdvance(x -> System.out.println("消费第一个元素：" + x));
        System.out.println("是否还有下一个：" + b);
        spliterator.tryAdvance(x -> System.out.println("消费第二个元素：" + x));
        // trySplit为拆分元素，调用一次拆分为原来 未消费时 的一半
        Spliterator<Integer> trySplit = spliterator.trySplit();
        // 按顺序消费原来的一半，因为上面已经消费掉了，因此从3开始
        trySplit.forEachRemaining(System.out::println);
        System.out.println("剩余元素个数，如果无法计算，则返回-1：" + spliterator.getExactSizeIfKnown());
        System.out.println("剩下那一半");
        spliterator.forEachRemaining(System.out::println);
        System.out.println("剩余元素个数，此处无限流情况下返回9223372036854775807，一般使用getExactSizeIfKnown：" + spliterator.estimateSize());
        // 获取spliterator的比较器
        System.out.println("比较器：" + Stream.iterate(0, i -> ++i).sorted().spliterator().getComparator());

        // 判断是否包含某个特征，计算方式是使用本身特征与传入特征进行与运算，得到的结果与传入特征值判断characteristics
        System.out.println("是否包含Spliterator.SIZED：" + spliterator.hasCharacteristics(Spliterator.SIZED));
        // 获取spliterator的特征值
        System.out.println("spliterator的特征值" + spliterator.characteristics());
        // 将spliterator转换为Stream流
        StreamSupport.stream(spliterator, false);
        // 将spliterator转换为Stream并行流
        StreamSupport.stream(spliterator, true);
    }
}
